import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.Skills;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class NatCrafter extends Script implements ServerMessageListener,
		PaintListener {

	private long startTime;
	private final RSTile[] path = { new RSTile(2767, 3122),
			new RSTile(2777, 3113), new RSTile(2783, 3103),
			new RSTile(2791, 3094), new RSTile(2800, 3085),
			new RSTile(2810, 3078), new RSTile(2821, 3069),
			new RSTile(2830, 3061), new RSTile(2837, 3051),
			new RSTile(2848, 3043), new RSTile(2857, 3034),
			new RSTile(2864, 3027), new RSTile(2869, 3022) };
	private final RSTile outRock_Tile = new RSTile(2869, 3019),
			inRock_Tile = new RSTile(2400, 4841);
	private final int npcID = 560, interfaceBuy = 232, interfaceConfirm = 228,
			exit = 2473, noteID = 7937, essence = 7936, wait1 = 450,
			wait2 = 700;
	private int used, made, curCount;
	private String doing = "Starting";

	int[] gemIDs = {};

	public String getName() {
		return "Nature Crafter";
	}

	// public String getAuthor() {
	// return "DarkGrounds";
	// }
	//
	// public double getVersion() {
	// return 1;
	// }

	public String getScriptCategory() {
		return "DarkGrounds";
	}

	public String getScriptDescription() {
		return "<html>\n"
				+ "<style type='text/css'> body {background-image: url('http://i358.photobucket.com/albums/oo30/ferretman86/NatCraftBG.jpg')}</style>"
				+ "<head></head>\n"
				+ "<body>\n"
				+ "<br><br><br><br><br><br><br><br><br><br><br>"
				+ "<center>"
				+ "<font color=yellow face=Verdana>"
				+ "Start in the Karamja General Store just south of Brimhaven.<br><br>"
				+ "You will need all your noted Pure Essence <br>and enough money to unnote it all (2 gp per)"
				+ "<br><br> Tiaras Equipped " + "</font></center>"
				+ "</body>\n" + "</html>";
	}

	public boolean onStart(Map<String, String> args) {
		startTime = System.currentTimeMillis();
		
		return true;
	}

	public void onFinish() {
		log("Crafted " + made + " Nature runes using " + used + " essence.");
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public int loop() {
		if (!inventoryContains(noteID)
				&& !inventoryContains(essence)
				&& isLoggedIn()
				&& RSInterface.getInterface(378).getChild(45).getAbsoluteX() != 207) {
			log("Out of Ess - Logging Out");
			stopAllScripts();
		}
		if (!isMoving() && getMyPlayer().getAnimation() == -1) {
			if (inventoryContains(essence)) {
				if (curCount < 1)
					curCount = getInventoryCount(essence);
				if (inAltar()) {
					if (tileOnScreen(inRock_Tile)) {
						doing = "Crafting Natures";
						clickMouse(randomPoint(Calculations
								.tileToScreen(inRock_Tile)), true);
					} else {
						doing = "Walking to Altar";
						walkTileMM(randomTile(checkTile(inRock_Tile, (1 / 2)),
								1, 0));
					}
				} else {
					if (distanceTo(outRock_Tile) > 4) {
						doing = "Walking to Rock";
						walk(false);
					} else {
						doing = "Entering Rock";
						if (tileOnScreen(outRock_Tile)) {
							clickMouse(randomPoint(Calculations
									.tileToScreen(outRock_Tile)), true);
						} else {
							doing = "Walking to Rock";
							walkTileMM(randomTile(outRock_Tile, 1));
						}
					}
				}
			} else {
				if (inAltar()) {
					doing = "Exiting";
					RSObject ext = findObject(exit);
					if (ext != null) {
						if (tileOnScreen(ext.getLocation()))
							atObject(ext, "Use");
						else {
							walkTileMM(randomTile(ext.getLocation(), 1));
						}
					}
				} else {
					if (distanceTo(path[0]) > 7) {
						doing = "Walking to Store";
						walk(true);
					} else {
						doing = "Exchanging Notes";
						if (RSInterface.getInterface(interfaceBuy).isValid()
								|| RSInterface.getInterface(interfaceConfirm)
										.isValid()) {
							if (RSInterface.getInterface(interfaceBuy)
									.isValid()) {
								clickMouse(random(243, 389), random(442, 458),
										true);
								wait(random(900, 1500));
								sendTextCustom(countInventory() + "");
								return random((wait1 + wait1 / 2),
										(wait2 + wait2 / 2));
							} else {
								atInterface(interfaceConfirm, 2);
							}
						} else {
							if (canContinue())
								clickContinue();
							else {
								RSNPC store = getNearestNPCByID(npcID);
								if (store != null) {
									if (distanceTo(store.getLocation()) < 5) {
										atInventoryItem(noteID, "Use");
										atNPC(store, "Jiminua");
										return random((wait1 + wait1 / 2),
												(wait2 + wait2 / 2));
									} else {
										walkTileMM(randomTile(store
												.getLocation(), 1));
									}
								}
							}
						}
					}
				}
			}
		}
		return random(wait1, wait2);
	}

	private int countInventory() {
		int count = 0;
		for (int id : getInventoryArray()) {
			if (id < 1)
				count++;
		}
		return count;
	}

	private void walk(boolean toStore) {
		setCompass('n');
		if (getEnergy() >= random(60, 100))
			setRun(true);
		RSTile start = locate();
		int loc = 0;
		for (int i = 0; i < path.length; i++) {
			if (start.equals(path[i])) {
				loc = i;
				break;
			}
		}
		if (toStore) {
			if (loc == 0) {
				walkTileMM(randomTile(path[0]));
				return;
			}
			walkTileMM(randomTile(path[loc - 1]));
		} else {
			if (loc == path.length - 1) {
				walkTileMM(randomTile(path[path.length - 1]));
				return;
			}
			walkTileMM(randomTile(path[loc + 1]));
		}
	}

	private RSTile locate() {
		RSTile min = path[0];
		for (int i = 1; i < path.length; i++) {
			if (distanceTo(path[i]) < distanceTo(min))
				min = path[i];
		}
		return min;
	}

	private Point randomPoint(Point click) {
		return new Point(click.x + random(-5, 5), click.y + random(-5, 5));
	}

	private RSTile randomTile(RSTile location) {
		return randomTile(location, 2);
	}

	private RSTile randomTile(RSTile location, int rand) {
		return randomTile(location, rand, rand);
	}

	private RSTile randomTile(RSTile location, int xRand, int yRand) {
		int x = location.getX(), y = location.getY();
		return new RSTile(x + random((-1 * xRand), xRand), y
				+ random((-1 * yRand), yRand));
	}

	private boolean isMoving() {
		if (!getMyPlayer().isMoving())
			return false;
		if (!inAltar()
				&& getDestination() != null
				&& (distanceBetween(path[0], getDestination()) > 5 && distanceBetween(
						path[path.length - 1], getDestination()) > 5)) {
			if (distanceTo(getDestination()) < 5)
				return false;
		}
		return true;
	}

	private boolean inAltar() {
		return distanceTo(inRock_Tile) <= 10;
	}

	private RSTile checkTile(RSTile tile, double amount) {
		if (tileOnMap(tile))
			return tile;
		RSTile loc = getMyPlayer().getLocation();
		RSTile check = new RSTile(
				(int) ((loc.getX() + tile.getX()) * (amount)), (int) ((loc
						.getY() + tile.getY()) * (amount)));
		if (!tileOnMap(check))
			check = checkTile(check, amount);
		return check;
	}

	private boolean sendTextCustom(String text) {
		sendText(text, false);
		String sent = RSInterface.getChildInterface(137, 51).getText();
		if (sent.length() > 2
				&& Character.toString(sent.charAt(sent.length() - 2)).equals(
						">")) {
			sendKey((char) KeyEvent.VK_ENTER);
			return true;
		}
		for (int i = 0; i < 5; i++) {
			sendKey((char) KeyEvent.VK_BACK_SPACE);
		}
		return false;
	}

	public void serverMessageRecieved(ServerMessageEvent e) {
		String word = e.getMessage().toLowerCase();
		if (word.contains("bind")) {
			used += curCount;
			int level = skills.getCurrentSkillLevel(Skills
					.getStatIndex("Runecraft"));
			if (level > 90) {
				made += curCount * 2;
			} else {
				made += curCount;
			}
			curCount = 0;
		}
	}

	public void onRepaint(Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			long hours = millis / (1000 * 60 * 60);
			millis -= hours * (1000 * 60 * 60);
			long minutes = millis / (1000 * 60);
			millis -= minutes * (1000 * 60);
			long seconds = millis / 1000;
			// 173 and 80 decide width and height respectively
			int topX = 515 - 190, topY = 337 - 80, x = topX + 5, y = topY + 5;
			g.setColor(new Color(0, 50, 100, 100));
			g.fill3DRect(topX, topY, 515 - topX, 337 - topY, true);
			g.setColor(Color.white);
			g.drawString("Runtime: " + hours + "h " + minutes + "min "
					+ seconds + "sec.", x, y += 15);
			g.drawString("Crafted: " + made + " Runes.", x, y += 15);
			g.drawString("Used: " + used + " essence.", x, y += 15);
			g.drawString("Status: " + doing, x, y += 15);
		}
	}

}